package com.fang.ademo;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilePermission;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity implements
		ActionBar.OnNavigationListener {

	/**
	 * The serialization (saved instance state) Bundle key representing the
	 * current dropdown position.
	 */
	private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
	private static final String TAG = "ADemoMain";
	private final static String localIpAddress = getLocalIpAddress();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// Set up the action bar to show a dropdown list.
		final ActionBar actionBar = getSupportActionBar();
		actionBar.setDisplayShowTitleEnabled(false);
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
		getRootAhth("chmod 777 " + getPackageCodePath());
		// Set up the dropdown list navigation in the action bar.
		actionBar.setListNavigationCallbacks(
		// Specify a SpinnerAdapter to populate the dropdown list.
				new ArrayAdapter<String>(actionBar.getThemedContext(),
						android.R.layout.simple_list_item_1,
						android.R.id.text1, new String[] {
								getString(R.string.title_section1),
								getString(R.string.title_section2),
								getString(R.string.title_section3), }), this);
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		// Restore the previously serialized current dropdown position.
		if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
			getSupportActionBar().setSelectedNavigationItem(
					savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		// Serialize the current dropdown position.
		outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getSupportActionBar()
				.getSelectedNavigationIndex());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	public boolean onNavigationItemSelected(int position, long id) {
		// When the given dropdown item is selected, show its contents in the
		// container view.
		getSupportFragmentManager()
				.beginTransaction()
				.replace(R.id.container,
						PlaceholderFragment.newInstance(position + 1)).commit();
		return true;
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {
		/**
		 * The fragment argument representing the section number for this
		 * fragment.
		 */
		private static final String ARG_SECTION_NUMBER = "section_number";
		private boolean isCanceled;
		public int id;
		private static Thread serverThread;

		/**
		 * Returns a new instance of this fragment for the given section number.
		 */
		public static PlaceholderFragment newInstance(int sectionNumber) {
			PlaceholderFragment fragment = new PlaceholderFragment();
			Bundle args = new Bundle();
			args.putInt(ARG_SECTION_NUMBER, sectionNumber);
			fragment.id = sectionNumber;
			fragment.setArguments(args);
			return fragment;
		}

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			final View rootView = inflater.inflate(R.layout.fragment_main,
					container, false);
			TextView textView = (TextView) rootView
					.findViewById(R.id.section_label);
			textView.setText(Integer.toString(getArguments().getInt(
					ARG_SECTION_NUMBER)));
			final int selectedIndex = this.id;
			TextView button1 = (TextView) rootView.findViewById(R.id.button1);
			button1.setOnClickListener(new View.OnClickListener() {

				public void onClick(View v) {

					TextView textView1 = (TextView) rootView
							.findViewById(R.id.textView1);
					TextView textView2 = (TextView) rootView
							.findViewById(R.id.textView2);
					if (3 == selectedIndex) {
						StringBuilder text = new StringBuilder();
						Log.d(TAG, "v.getParent().toString() = "
								+ v.getParent().toString());
						Log.d(TAG,
								"rootView.toString() = " + rootView.toString());
						Log.d(TAG, "isRoot() = " + isRoot());

						File hostsFile = new File("/system/etc/hosts");
						try {
							// FileInputStream fileInputStream = new
							// FileInputStream(new File("/system/etc/host"));
							// InputStreamReader inputStreamReader = new
							// InputStreamReader(fileInputStream);
							FileReader fileReader = new FileReader(hostsFile);
							FilePermission filePermission = new FilePermission(
									"/system/etc/hosts", "write");
							Log.d(TAG, "filePermission.getActions() = "
									+ filePermission.getActions());
							// System.getSecurityManager().checkWrite("/system/etc/hosts");
							Log.d(TAG,
									"hostsFile.canWrite() = "
											+ hostsFile.canWrite());

							BufferedReader bufferedReader = new BufferedReader(
									fileReader);
							char[] buffer = new char[10 * 1024];
							bufferedReader.read(buffer);
							textView2.setText(new String(buffer));
							bufferedReader.close();
						} catch (FileNotFoundException e) {
							text.append(e.toString());

						} catch (IOException e) {
							text.append(e.toString());
						}
						textView1.setText(text);
					} else if (1 == selectedIndex) {
						// <uses-permission
						// android:name="android.permission.INTERNET"/>
						String msg = localIpAddress + ", Client Message "
								+ Math.random();
						byte[] message = msg.getBytes();
						Log.d("Client Socket", " Send message : " + msg);
						try {
							// 创建一个Socket对象，指定服务器端的IP地址和端口号"192.168.1.105"
							Socket socket = new Socket(localIpAddress, 4567);
							// 从Socket对象中得到OutputStream对象，准备往OutputStream对象里写入数据
							OutputStream outputStream = socket
									.getOutputStream();
							outputStream.write(message, 0, message.length);
							outputStream.flush();
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else if (2 == selectedIndex) {
						isCanceled = true;
					}
				}
			});
			if (1 == selectedIndex) {
				button1.setText("Send Socket");
			} else if (2 == selectedIndex) {
				Log.d("ServerSocket", "onCreateView, serverThread = "
						+ serverThread);
				button1.setText("Stop ServerSocket");
				if (null == serverThread) {
					serverThread = new Thread() {
						@Override
						public void run() {

							// 声明一个ServerSocket对象
							ServerSocket serverSocket = null;
							try {
								// 创建一个ServerSocket对象,并让ServerSocket在4567端口上监听
								serverSocket = new ServerSocket(4567);
								while (true && !isCanceled) {
									Log.d("ServerSocket",
											"serverSocket.accept() blocks.");
									// 调用ServerSocket对象的accept()方法接收客户端所发送的请求
									// accept()这个方法是一个阻塞的方法，如果客户端没有发送请求，那么代码运行到这里被阻塞，停在这里不再向下运行了，一直等待accept()函数的返回,这时候突然客户端发送一个请求，那个这个方法就会返回Socket对象，
									// Socket对象代表服务器端和客户端之间的一个连接
									Socket socket = serverSocket.accept();
									Log.d("ServerSocket",
											"serverSocket.accept() release.");
									// 从Socket对象中得到InputStream对象
									// 一旦通讯管道建立起来后,就是服务器端有一个Socket,客户端也有一个Socket,我们就可以通过服务器端的Socket里面的InputStream来读取客户端所发送的数据
									InputStream inputStream = socket
											.getInputStream();
									byte data[] = new byte[1024 * 4];
									int i = 0;
									isCanceled = false;
									// 从InputStream对象中读取客户端所发送的数据
									while ((i = inputStream.read(data)) != -1
											&& !isCanceled) {
										Log.d("ServerSocket", new String(data,
												0, i));
										break;
									}
									Log.d("ServerSocket", "socket.close()");
									socket.close();
								}

							} catch (IOException e) {
								e.printStackTrace();
							} finally {
								try {
									if (null != serverSocket)
										serverSocket.close();
								} catch (IOException e) {
									e.printStackTrace();
								}
								Log.d("ServerSocket", "finally");
								serverThread = null;
							}
						}

					};
					serverThread.start();
				}
			}
			return rootView;
		}
	}

	public static String getLocalIpAddress() {
		try {
			InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface
					.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				for (Enumeration<InetAddress> enumIpAddr = intf
						.getInetAddresses(); enumIpAddr.hasMoreElements();) {
					InetAddress inetAddress = enumIpAddr.nextElement();
					if (!inetAddress.isLoopbackAddress()) {
						return inetAddress.getHostAddress().toString();
					}
				}
			}
		} catch (SocketException ex) {
		}
		return null;
	}

	/**
	 * root 的判断标准 在path 下面包含su 文件 并且su 文件的权限是可读，可写，可执行。 如何判断手机是否已经root了，输入adb
	 * shell回车,su 回车,如果出现#,那么你的手机的确ROOT了。
	 * 
	 * @return
	 */
	public static boolean isRoot() {
		String sys = System.getenv("PATH");
		ArrayList<String> commands = new ArrayList<String>();
		String[] path = sys.split(":");
		for (int i = 0; i < path.length; i++) {
			String commod = "ls -l " + path[i] + "/su";
			commands.add(commod);
		}
		ArrayList<String> res = shellRun("/system/bin/sh",
				commands.toArray(new String[commands.size()]));
		String[] cmdResponse;
		for (int i = 0; i < res.size(); i++) {
			cmdResponse = res.get(i).split("[\t ]+");
			// Log.d(TAG, "command Response : " + res.get(i));
			if (3 <= cmdResponse.length) {
				Log.d(TAG, "cmdResponse : " + Arrays.toString(cmdResponse));
				if ("-rwsr-sr-x".equals(cmdResponse[0])
						&& "root".equals(cmdResponse[1])
						&& "root".equals(cmdResponse[2]))
					return true;
			}
		}
		return false;

	}

	public synchronized boolean getRootAhth(String command) {
		Process process = null;
		DataOutputStream os = null;
		try {
			process = Runtime.getRuntime().exec("su");
			os = new DataOutputStream(process.getOutputStream());
			if (null != command)
				os.writeBytes(command + "\n");
			os.writeBytes("exit\n");
			os.flush();
			int exitValue = process.waitFor();
			if (exitValue == 0) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			Log.d("*** DEBUG ***", "Unexpected error - Here is what I know: "
					+ e.getMessage());
			return false;
		} finally {
			try {
				if (os != null) {
					os.close();
				}
				process.destroy();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static ArrayList<String> shellRun(String shell, String[] commands) {
		ArrayList<String> output = new ArrayList<String>();
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(shell);

			BufferedOutputStream shellInput = new BufferedOutputStream(
					process.getOutputStream());
			BufferedReader shellOutput = new BufferedReader(
					new InputStreamReader(process.getInputStream()));

			for (String command : commands) {
				Log.i(TAG, "command: " + command);
				shellInput.write((command + " 2>&1\n").getBytes());
			}

			shellInput.write("exit\n".getBytes());
			shellInput.flush();

			String line;
			while ((line = shellOutput.readLine()) != null) {
				Log.i(TAG, "result: " + line);
				output.add(line);
			}

			process.waitFor();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			process.destroy();
		}

		return output;
	}

	static {
		// load library: libADemo.so
		try {
			System.loadLibrary("ADemo");
		} catch (UnsatisfiedLinkError ule) {
			System.err.println("WARNING: Could not load library!");
		}

	}

	private native String method(String paramString1);
}
